#!/bin/bash
# This script switch only from default ISP.

if [ "$#" -lt '3' ]; then
	echo "Usage: $0 [masq] start|stop|restart EXT_IF LOCAL_IP [port] [proto]
If masq defined then rules will add to masq.sh file only for next using
example:
	$0 start ppp1 192.168.1.20
	$0 start ppp1 192.168.1.20 tcp 80
	$0 start ppp1 192.168.1.20 tcp 80 123.234.123.234
	$0 start ppp1 192.168.1.20 '*'"

	exit 0
fi

masqfile="$TWMFOLDER/modules/traffic_routing/masquearading.sh"

if [ ! -e $masqfile ]; then
	echo "#!/bin/bash" > $masqfile
	chmod 710 $masqfile
fi

function logDebug()
{
	if [ "$debug" = "1" ]; then
		echo "$@"
	fi
}

function toMASQ()
{
	logDebug $1
	if [ "$MASQ" = "1" ]; then
		echo "$1" >> $masqfile
	else
		$1
#		echo "# $1" >> $masqfile
	fi
}

MASQ=0
if [ "$1" = "masq" ]; then
	MASQ=1
	shift
fi


ACTION=$1
EXT_IF=$2
LOCAL_IP=$3
PROTO=$4
DPORT=$5
DHOST=$6



# Remove '' quotes
if [[ $DPORT =~ "'(.+)'" ]]; then
	DPORT="${BASH_REMATCH[1]}"
fi

DEFAULT_GW_IF=`ip route | grep default | gawk '{print $5}'`
if [ "$DEFAULT_GW_IF" = "$EXT_IF" ]; then
	echo "You can't switch traffic to default GW ($EXT_IF)."
	exit 0
fi
if [ "$DPORT"  = "" ]; then
	DPORT='*'
fi
if [ "$PROTO"  = "" ]; then
	PROTO='tcp'
fi
if [ "$DHOST"  = "" ]; then
	DHOST='*'
fi


declare -a COMMON_VARIABLES
COMMON_VARIABLES=(`perl $TWMFOLDER/bin/get_varMultipleValue.pl debug_mode debug_log grep gawk date cat iptables ip _DEFAULT_`)
debug=${COMMON_VARIABLES[0]}
debug_log="${TWMFOLDER}logs/${COMMON_VARIABLES[1]}"
grep=${COMMON_VARIABLES[2]}
gawk=${COMMON_VARIABLES[3]}
date=${COMMON_VARIABLES[4]}
cat=${COMMON_VARIABLES[5]}
iptables=${COMMON_VARIABLES[6]}
ip_tool=${COMMON_VARIABLES[7]}

isp=(`perl $TWMFOLDER/bin/get_varISP.pl`)
for item in ${isp[*]}
do
	echo $item
	intf=(`echo $item | sed -e "s/:/ /g"`)
	if [ "${intf[0]}" = "$EXT_IF" ]; then
		ISP_NAME=${intf[7]}
		MARK_NUM=${intf[5]}
	fi
	if [ "${intf[3]}" = "1" ]; then
		LOCAL_IF=${intf[0]}
		INT_IP=${intf[1]}
	fi
	if [ "${intf[4]}" = "1" ]; then
		DEFAULT_ISP_IF=${intf[0]}
	fi
done

if [ "$ISP_NAME" = "" ]; then
	logDebug "ISP name can not be empty"
fi
if [ "$MARK_NUM" = "" ]; then
	logDebug "Network mark can not be empty"
fi
if [ "$LOCAL_IF" = "" ]; then
	logDebug "Local interface can not be empty"
fi
if [ "$INT_IP" = "" ]; then
	logDebug "Local interface ip can not be empty"
fi
if [ "$DEFAULT_ISP_IF" = "" ]; then
	logDebug "Default ISP interface can not be empty"
fi


SQUID_PORTS=(`perl $TWMFOLDER/modules/http_logging/get_squid_data.pl`)
for item in ${SQUID_PORTS[*]}
do
	if [ -n "$item" ]; then
		intf=(`echo $item | sed -e "s/:/ /g"`)
		if [ "${intf[1]}" = "$DEFAULT_ISP_IF" ]; then
			DEFAULT_SQUID_PORT=${intf[0]}
		fi
		if [ "${intf[1]}" = "$EXT_IF" ]; then
			EXT_SQUID_PORT=${intf[0]}
		fi
	fi
done


function isp_marker()   
{
	_DPORT=$3
	_DHOST=$5
	_ACTION=$1
	_PROTO=$4
	_IP=$2
	if [ "$_DPORT" != "*" ] ; then
		MULTIPORT=`echo -n "$_DPORT" | grep -E "," | wc -l`
		if [ "$MULTIPORT" = "1" ] ; then
			DPRT="-m multiport --destination-port $_DPORT"
			SPRT="-m multiport --source-port $_DPORT"
		else
			DPRT="--dport $_DPORT"
			SPRT="--sport $_DPORT"
		fi
	fi
	if [ "$_DHOST" == "*" ] ; then
#		_DHOST="! --destination $INT_IP"
		_DHOST=""
	else
		_DHOST=" --destination $_DHOST"
	fi

# openSuSe 12.1 can not route by package mark. or there is some tricky
	_ENABLE_RULE=`cat /etc/issue | grep "12.1" | wc -l`
	if [ "$_ENABLE_RULE" = "1" ]; then
		_ROUTE_ACTION="add"
		if [ "$_ACTION" = "D" ] ; then
			_ROUTE_ACTION="del"
		fi
		_ROUTE_TABLE=`ip rule list | grep "fwmark $MARK_NUM lookup" | gawk '{print $7}'`
		if [ "$_ROUTE_TABLE" != "" ] ; then
			_IS_RULE=`$ip_tool rule list | grep "from $_IP lookup $_ROUTE_TABLE" | wc -l`
			if [ "$_IS_RULE" = '0' ] && [ "$_ROUTE_ACTION" = "add" ]; then
				toMASQ "$ip_tool rule $_ROUTE_ACTION from $_IP table $_ROUTE_TABLE"
			elif [ "$_ROUTE_ACTION" = "del" ]; then
				_IS_ANY_RULE=`cat $TWMFOLDER/modules/traffic_routing/conf/config.xml | grep ">$_IP<" | wc -l`
				if [ "$_IS_ANY_RULE" = "0" ]; then
					toMASQ "$ip_tool rule $_ROUTE_ACTION from $_IP table $_ROUTE_TABLE"
				fi
			fi
		fi
	fi

	toMASQ "$iptables -t mangle -$_ACTION PREROUTING -p $_PROTO -s $_IP $_DHOST $DPRT -j MARK --set-mark $MARK_NUM"
	toMASQ "$iptables -t nat -$_ACTION POSTROUTING -p $_PROTO -s $_IP $_DHOST $DPRT -o $EXT_IF -m mark --mark $MARK_NUM -j MASQUERADE"
	if [ "$_PROTO" = "tcp" ] ; then
		PORT80=`echo -n ,$_DPORT, | grep -E ",80," | wc -l`
		if [ "$PORT80" = "1" ] || [ "$_DPORT" = "*" ]; then
			toMASQ "$iptables -t nat -$_ACTION PREROUTING -i $LOCAL_IF -p $_PROTO -s $_IP $_DHOST -m mark --mark $MARK_NUM --dport 80 -j ACCEPT";
		fi
		PORT21=`echo -n ,$_DPORT, | grep -E ",21," | wc -l`
		if [ "$PORT21" = "1" ]; then
			toMASQ "$iptables -t mangle -$_ACTION PREROUTING -p $_PROTO -s $_IP $_DHOST --dport ftp-data -j MARK --set-mark $MARK_NUM"
		fi
	fi
	if [ "$_ACTION" = "I" ] ; then
		logDebug "Started rules to move $PROTO traffic $LOCAL_IP:$DPORT to $EXT_IF"
	else
		logDebug "Stopped rules to move $PROTO traffic $LOCAL_IP:$DPORT to $EXT_IF"
	fi
}



set -e

case $ACTION in
start)
#	if [ "$DPORT" = "*" ]; then
#		IS_SPEC_ISP_UP=`$iptables -t mangle -L -n | $grep -E "MARK set $MARK_NUM" | $grep "$LOCAL_IP " | $grep -v dpt | $grep $PROTO | wc -l`
#    else
#		IS_SPEC_ISP_UP=`$iptables -t mangle -L -n | $grep -E "MARK set $MARK_NUM" | $grep "$LOCAL_IP " | $grep dpt:"$DPORT" | $grep $PROTO | wc -l`
#    fi
#   	if [ "$IS_SPEC_ISP_UP" = "0" ]; then
        isp_marker "I" $LOCAL_IP "$DPORT" "$PROTO" "$DHOST"
#    else
#		logDebug "Required rule is started already: $LOCAL_IP $DPORT $PROTO"
#    fi
    ;;
stop)
	isp_marker "D" $LOCAL_IP "$DPORT" "$PROTO" "$DHOST"
    ;;
restart)
    shift
    $0 stop
	sleep 1
    $0 start "$@"
    ;;
*)
	N=isp_marking.sh
	echo "Usage: $N {start|stop|restart}" >&2
	exit 1
	;;
esac

exit 0
